/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of salil64

	salil64 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	salil64 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with salil64.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <lib.h>
#include <print.h>

void kPrintHex(unsigned long num)
{
	char q;
	char trail = 0;
	unsigned long div = 0x1000000000000000;
	print("0x", 2);
	do {
		q = num / div;
		num = num - q * div;
		if(q > 0x9) {
			q = q - 0xa + 'a';
			print(&q, 1);
			trail = 1;
		} else {
			if(q || trail) {
				q = q + '0';
				print(&q, 1);
				trail = 1;
			}
		}
		div = div / 0x10;
	} while(div > 0);
	if(!trail)
		print("0", 1);
}


//2^64 = 18446744073709552000

void kPrintDec(long num)
{
	char q;
	char trail = 0;
	if(num < 0) {
		print("-", 1);
		num = -num;
	}
	unsigned long div = 1000000000000000000;
	do {
		q = num / div;
		num = num - q * div;
		if(q || trail) {
			q = q + '0';
			print(&q, 1);
			trail = 1;
		}
		div = div / 10;
	} while(div > 0);
	if(!trail)
		print("0", 1);
}

void kPrint(const char *msg)
{
	print(msg, strlen(msg));
}


/**
 * Print character for hex printing
 * Doesn't show special characters (Those that may not be displayed)
 */
static void memchar(char c)
{
	if(c >= '!' && c <= '~') {
		print(&c, 1);
	} else {
		print(".", 1);
	}
}

/**
 * Print memory like a hex editor :P
 */
int kPrintMemory(void *start, unsigned long len)
{
	char *c;
	unsigned long i, j, max;
	c = start;
	for(i = 0; i < len; i += 64) {
		kPrintHex((unsigned long)(c+i));
		max = 64 < (len - i) ? 64 : len - i;
		for(j = 0; j < max; j++) {
			memchar((char)*(c+i+j));
		}
		print("\n", 1);
	}
	return 0;
}
